---
title: Authenticate your operations
---

> Authentication is not included in the GraphQL specification. This page aims at giving some guidance for the most common scenarios but doesn't intend to be exhaustive.

## Authenticating your HTTP requests with OkHttp

[OkHttp Interceptors](https://square.github.io/okhttp/features/interceptors/) are an easy way to add an `"Authorization"` header to your HTTP requests.

OkHttp Interceptors have been around for a long time and work well but can only be used with Apollo Kotlin on Android and the JVM.

## Authenticating your HTTP requests with Apollo HttpInterceptor

In order to authenticate your HTTP requests in a multi-platform way, you can use an Apollo [HttpInterceptor](./interceptors-http).

HttpInterceptor is multiplatform and uses an API very similar to OkHttp's:

```kotlin
class AuthorizationInterceptor() : HttpInterceptor {
  private val mutex = Mutex()

  override suspend fun intercept(request: HttpRequest, chain: HttpInterceptorChain): HttpResponse {
    var token = mutex.withLock {
      // get current token
    }

    val response = chain.proceed(request.newBuilder().addHeader("Authorization", "Bearer $token").build())

    return if (response.statusCode == 401) {
      token = mutex.withLock {
        // get new token
      }
      chain.proceed(request.newBuilder().addHeader("Authorization", "Bearer $token").build())
    } else {
      response
    }
  }
}
```

For a more advanced example, you can take a look at the [AuthorizationInterceptor integration tests](https://github.com/apollographql/apollo-kotlin/blob/6f0b798198c215013f12e7da509624a1befc1b73/apollo-runtime/src/commonTest/kotlin/com/apollographql/apollo3/network/AuthorizationInterceptor.kt#L30)

## Authenticating your WebSockets

Authenticating WebSockets is typically handled with a specific connection payload:

```kotlin
val apolloClient = ApolloClient.Builder()
    .httpServerUrl("http://localhost:8080/graphql")
    .webSocketServerUrl("http://localhost:8080/subscriptions")
    .wsProtocol(
        SubscriptionWsProtocol.Factory(
            connectionPayload = {
              // some servers use "authorization" directly
              mapOf("authorization" to token)   // highlight-line
              // others require to wrap in a "headers" map
              mapOf("headers" to mapOf("authorization" to token))
              // others will expect different maps
              // refer to your backend docs for the actual map to use
            }
        )
    )
    .build()

```

Alternatively, you can also send headers in the initial WebSocket handshake request:

```kotlin
val apolloClient = ApolloClient.Builder()
    .httpServerUrl("https://example.com/graphql")
    .subscriptionNetworkTransport(
        WebSocketNetworkTransport.Builder()
            .serverUrl("https://example.com/subscriptions")
            .addHeader("Authorization", authorization) // highlight-line
            .build()
    )
    .build()
```

### Updating your WebSocket token

When using authenticated subscriptions over WebSockets, you might want to refresh your authentication token because it was invalidated or simply because it expired.

<Note>

If your user logged out, you might want to consider creating a new `ApolloClient` instead. This will make sure that all other state besides the WebSocket, like cache for an example, is new and not shared amongst different users.

</Note>

Sometimes the websocket will emit an error that you can use in `webSocketReopenWhen` to create a new WebSocket. Other times that information will come from elsewhere in your app, and you have to force disconnect the WebSocket.

First define your own Exception:

```kotlin
class WebSocketReconnectException: Exception("The WebSocket needs to be reopened")
```

```kotlin
    val apolloClient = ApolloClient.Builder()
        .httpServerUrl("http://localhost:8080/graphql")
        .webSocketServerUrl("http://localhost:8080/subscriptions")
        .wsProtocol(
            SubscriptionWsProtocol.Factory(
                connectionPayload = {
                  // the connection_init payload
                  // This is an example. You will most likely have to tweak it for your backend
                  mapOf("Authorization" to token)
                }
            )
        )
        .webSocketReopenWhen { e, attempt ->
          if (e is WebSocketReconnectException) {
            true
          } else {
            // Another WebSocket error happened, decide what to do with it
            // Here we're trying to reconnect at most 3 times
            attempt < 3
          }
        }
        .build()
```

When you need to reopen the WebSocket, call `closeConnection`:

```kotlin
apolloClient.subscriptionNetworkTransport.closeConnection(WebSocketReconnectException())`
```

The WebSocket will close and reopen with a fresh new `connectionPayload`.

